home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource5 / 311_01 / db_var.c < prev    next >
C/C++ Source or Header  |  1990-04-23  |  11KB  |  456 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      db_var.c  v1.3  (c) 1990  Ken Harris                                */
  5. /*                                                                          */
  6. /*                                                                          */
  7. /****************************************************************************/
  8. /*                                                                          */
  9. /*      This software is made available on an AS-IS basis. Unrestricted     */
  10. /*      use is granted provided that the copyright notice remains intact.   */
  11. /*      The author makes no warranties expressed or implied.                */
  12. /*                                                                          */
  13. /****************************************************************************/
  14.  
  15. #include "dblib.h"
  16.  
  17. #ifdef ANSI
  18. void db_var_bld_csum(BUFFER);
  19. void db_var_chk_csum(BUFFER);
  20. #else
  21. void db_var_bld_csum();
  22. void db_var_chk_csum();
  23. #endif
  24.  
  25. /*
  26.  *      db_add_var  -  Add a record to a variable file
  27.  */
  28.  
  29. void db_add_var(df, user_data, data_size)
  30.  DATA_FILE df;
  31.  char *user_data;
  32.  int data_size;
  33. {
  34.         FILE_HDR  fh;
  35.         BUFFER   buf;
  36.         VAR_REC  vbuf;
  37.  
  38.         db_error = 0;
  39.  
  40.         fh  = (FILE_HDR) df->df_fhdr->buf_data;
  41.         buf = df->df_buf;
  42.  
  43.         buf->buf_cur_blk  = fh->fh_vfile_size;
  44.         buf->buf_rec_inx  = 0;
  45.     buf->buf_cur_size = sizeof(struct db_var_rec) + data_size;
  46.  
  47.     if (data_size < 1 || buf->buf_cur_size > buf->buf_size)
  48.     {    db_error = DB_VAR_SIZE_ERROR;
  49.         return;
  50.     }
  51.  
  52.         db_add_blk = buf->buf_cur_blk;
  53.         db_add_rec = buf->buf_rec_inx;
  54.  
  55.         vbuf = (VAR_REC) buf->buf_data;
  56.     vbuf->var_stat  = DB_INUSE;
  57.     vbuf->var_dsize = data_size;
  58.  
  59.         memcpy(vbuf->var_data, user_data, data_size);
  60.     db_var_bld_csum(buf);
  61.  
  62.         fh->fh_rec_cnt++;
  63.     fh->fh_vfile_size += buf->buf_cur_size;
  64.  
  65.         db_put_blk(df,df->df_fhdr);
  66.         db_put_blk(df,buf);
  67. }
  68.  
  69. /*
  70.  *      db_read_first_var  -  Read First Record in a Variable File
  71.  */
  72.  
  73. void db_read_first_var(df, user_data, data_size)
  74.  DATA_FILE df;
  75.  char *user_data;
  76.  int  *data_size;
  77. {
  78.         FILE_HDR fh;
  79.         BUFFER  buf;
  80.         VAR_REC vrec;
  81.         ulong   psn;
  82.  
  83.         db_error = 0;
  84.  
  85.         fh   = (FILE_HDR) df->df_fhdr->buf_data;
  86.         buf  = df->df_buf;
  87.     vrec = (VAR_REC) buf->buf_data;
  88.  
  89.         for (psn=DB_FILE_HDR_SIZE; psn < fh->fh_vfile_size;)
  90.         {       db_get_blk(df, psn, buf);
  91.                 if (db_error) return;
  92.  
  93.         db_var_chk_csum(buf);
  94.         if (db_error) return;
  95.  
  96.         buf->buf_cur_size = sizeof(struct db_var_rec) 
  97.                   + vrec->var_dsize;
  98.  
  99.         if (vrec->var_stat == DB_INUSE)
  100.         {    *data_size = vrec->var_dsize;
  101.             memcpy(user_data, vrec->var_data, *data_size);
  102.             return;
  103.         }
  104.  
  105.         psn += buf->buf_cur_size;
  106.         }
  107.         db_error= DB_END_OF_FILE;
  108. }
  109.  
  110. /*
  111.  *      db_read_next_var  -  Read Next Record in a Variable File
  112.  */
  113.  
  114. void db_read_next_var(df, user_data, data_size)
  115.  DATA_FILE df;
  116.  char *user_data;
  117.  int  *data_size;
  118. {
  119.         FILE_HDR fh;
  120.         BUFFER  buf;
  121.         VAR_REC vrec;
  122.         ulong   psn;
  123.  
  124.         db_error = 0;
  125.  
  126.         fh   = (FILE_HDR) df->df_fhdr->buf_data;
  127.         buf  = df->df_buf;
  128.         vrec = (VAR_REC) buf->buf_data;
  129.  
  130.     psn = df->df_prev_blk + df->df_prev_vsize;
  131.  
  132.         while (psn < fh->fh_vfile_size)
  133.         {       db_get_blk(df, psn, buf);
  134.                 if (db_error) return;
  135.  
  136.         db_var_chk_csum(buf);
  137.         if (db_error) return;
  138.  
  139.         buf->buf_cur_size = sizeof(struct db_var_rec) 
  140.                   + vrec->var_dsize;
  141.  
  142.         if (vrec->var_stat == DB_INUSE)
  143.         {    *data_size = vrec->var_dsize;
  144.             memcpy(user_data, vrec->var_data, *data_size);
  145.             return;
  146.         }
  147.  
  148.         psn += buf->buf_cur_size;
  149.         }
  150.         db_error= DB_END_OF_FILE;
  151. }
  152.  
  153. /*
  154.  *      db_read_last_var  -  Read Last Record in a Variable File
  155.  */
  156.  
  157. void db_read_last_var(df, user_data, data_size)
  158.  DATA_FILE df;
  159.  char *user_data;
  160.  int  *data_size;
  161. {
  162.         FILE_HDR fh;
  163.         BUFFER  buf;
  164.         VAR_REC vrec;
  165.         ulong   psn;
  166.     char   *c, *d;
  167.     short   vsize;
  168.  
  169.  
  170.         db_error = 0;
  171.  
  172.         fh   = (FILE_HDR) df->df_fhdr->buf_data;
  173.         buf  = df->df_buf;
  174.  
  175.         for (psn=fh->fh_vfile_size; psn >= DB_FILE_HDR_SIZE;)
  176.         {       psn -= buf->buf_size;
  177.         db_get_blk(df, psn, buf);
  178.                 if (db_error) return;
  179.         psn = buf->buf_cur_blk;
  180.  
  181.         c = buf->buf_data + buf->buf_cur_size - 2;
  182.         d = (char *)&vsize;
  183.  
  184.         *d++ = *c++;
  185.         *d   = *c;
  186.  
  187.         buf->buf_rec_inx  = buf->buf_size 
  188.                   - sizeof(struct db_var_rec) - vsize;
  189.         buf->buf_cur_size = sizeof(struct db_var_rec) + vsize;
  190.  
  191.         db_var_chk_csum(buf);
  192.         if (db_error) return;
  193.  
  194.         vrec = (VAR_REC)(buf->buf_data + buf->buf_rec_inx);
  195.  
  196.         if (vrec->var_stat == DB_INUSE)
  197.         {    *data_size = vrec->var_dsize;
  198.             memcpy(user_data, vrec->var_data, *data_size);
  199.             return;
  200.         }
  201.         }
  202.         db_error= DB_END_OF_FILE;
  203. }
  204.  
  205. /*
  206.  *      db_read_prev_var  -  Read Previous Record in a Variable File
  207.  */
  208.  
  209. void db_read_prev_var(df, user_data, data_size)
  210.  DATA_FILE df;
  211.  char *user_data;
  212.  int  *data_size;
  213. {
  214.         FILE_HDR fh;
  215.         BUFFER  buf;
  216.         VAR_REC vrec;
  217.         ulong   psn;
  218.     char   *c, *d;
  219.     short   vsize;
  220.  
  221.  
  222.         db_error = 0;
  223.  
  224.         fh   = (FILE_HDR) df->df_fhdr->buf_data;
  225.         buf  = df->df_buf;
  226.  
  227.         for (psn=df->df_prev_blk+df->df_prev_rec; psn >= DB_FILE_HDR_SIZE;)
  228.         {       psn -= buf->buf_size;
  229.         db_get_blk(df, psn, buf);
  230.                 if (db_error) return;
  231.         psn = buf->buf_cur_blk;
  232.  
  233.         c = buf->buf_data + buf->buf_cur_size - 2;
  234.         d = (char *)&vsize;
  235.  
  236.         *d++ = *c++;
  237.         *d   = *c;
  238.  
  239.         buf->buf_rec_inx  = buf->buf_cur_size 
  240.                   - sizeof(struct db_var_rec) - vsize;
  241.         buf->buf_cur_size = sizeof(struct db_var_rec) + vsize;
  242.  
  243.         db_var_chk_csum(buf);
  244.         if (db_error) return;
  245.  
  246.         vrec = (VAR_REC)(buf->buf_data + buf->buf_rec_inx);
  247.  
  248.         if (vrec->var_stat == DB_INUSE)
  249.         {    *data_size = vrec->var_dsize;
  250.             memcpy(user_data, vrec->var_data, *data_size);
  251.             return;
  252.         }
  253.         }
  254.         db_error= DB_END_OF_FILE;
  255. }
  256.  
  257. /*
  258.  *      db_update_var  -  Update Record in a Variable File
  259.  */
  260.  
  261. void db_update_var(df, user_data)
  262.  DATA_FILE df;
  263.  char *user_data;
  264. {
  265.         FILE_HDR  fh;
  266.         BUFFER   buf;
  267.         VAR_REC  vrec;
  268.  
  269.         db_error = 0;
  270.  
  271.         fh  = (FILE_HDR) df->df_fhdr->buf_data;
  272.         buf = df->df_buf;
  273.  
  274.         if (buf->buf_cur_blk == 0)
  275.         {       db_error = DB_NO_CURRENT_REC;
  276.                 return;
  277.         }
  278.  
  279.     vrec = (VAR_REC)(buf->buf_data + buf->buf_rec_inx);
  280.  
  281.         if (vrec->var_stat != DB_INUSE)
  282.         {       db_error = DB_DELETED_REC;
  283.                 return;
  284.         }
  285.  
  286.         memcpy(vrec->var_data, user_data, vrec->var_dsize);
  287.  
  288.     db_var_bld_csum(buf);
  289.  
  290.         db_put_blk(df, buf);
  291. }                           
  292.  
  293. /*
  294.  *      db_delete_var  -  Delete Record in a Variable File
  295.  */
  296.  
  297. void db_delete_var(df)
  298.  DATA_FILE df;
  299. {
  300.         FILE_HDR  fh;
  301.         BUFFER   buf;
  302.         VAR_REC  vrec;
  303.     char    *c;
  304.     int      i;
  305.  
  306.         db_error = 0;
  307.  
  308.         fh  = (FILE_HDR) df->df_fhdr->buf_data;
  309.         buf = df->df_buf;
  310.  
  311.         if (buf->buf_cur_blk == 0)
  312.         {       db_error = DB_NO_CURRENT_REC;
  313.                 return;
  314.         }
  315.  
  316.     vrec = (VAR_REC)(buf->buf_data + buf->buf_rec_inx);
  317.  
  318.         if (vrec->var_stat != DB_INUSE)
  319.         {       db_error = DB_DELETED_REC;
  320.                 return;
  321.         }
  322.  
  323.     vrec->var_stat = DB_FREE;
  324.     for (i=0, c=vrec->var_data; i < vrec->var_dsize; i++) *c++ = 0;
  325.  
  326.     fh->fh_rec_cnt--;
  327.  
  328.     db_var_bld_csum(buf);
  329.  
  330.         db_put_blk(df, buf);
  331.     db_put_blk(df,buf);
  332. }                           
  333.  
  334. /*
  335.  *      db_reorg_var  -  Reorganize a Variable File 
  336.  */
  337.  
  338. void db_reorg_var(new_df)
  339.  DATA_FILE new_df;
  340. {
  341.     DATA_FILE old_df;
  342.     FILE_HDR  old_fh, new_fh;
  343.         char     *vrec, *calloc();
  344.     int       vsize;
  345.  
  346.  
  347.         db_error = 0;
  348.  
  349.         old_df = (DATA_FILE) calloc(1, sizeof(struct db_data_file));
  350.     if (!old_df)
  351.     {    db_error = DB_ALLOC_ERROR;
  352.         return;
  353.     }
  354.  
  355.         old_df->df_fhdr = db_alloc_buf(DB_FILE_HDR_SIZE);
  356.         old_fh          = (FILE_HDR) old_df->df_fhdr->buf_data;
  357.     if (db_error) { db_free_df(old_df); return; }
  358.  
  359.         new_fh = (FILE_HDR) new_df->df_fhdr->buf_data;
  360.     memcpy(old_fh, new_fh, sizeof(struct db_file_hdr));
  361.  
  362.     new_fh->fh_rec_cnt    = 0;
  363.     new_fh->fh_vfile_size = DB_FILE_HDR_SIZE;
  364.  
  365.         old_df->df_stat = DB_OPEN;
  366.     old_df->df_fd   = new_df->df_fd;
  367.  
  368.         old_df->df_buf = db_alloc_buf(old_fh->fh_block_size);
  369.     if (db_error) { db_free_df(old_df); return; }
  370.  
  371.     vrec = calloc(1, old_fh->fh_data_size);
  372.     if (!vrec)
  373.     {    db_error = DB_ALLOC_ERROR;
  374.         return;
  375.     }
  376.  
  377.     db_read_first(old_df, vrec, &vsize);
  378.     while (!db_error)
  379.     {    db_add(new_df, vrec, vsize);
  380.         if (db_error) break;
  381.  
  382.         db_read_next(old_df, vrec, &vsize);
  383.     }
  384.  
  385.     if (db_error == DB_END_OF_FILE) db_error = 0;
  386.  
  387.     free(vrec);
  388.     db_free_df(old_df);
  389. }
  390.  
  391. /*
  392.  *      db_var_bld_csum - Compute var record check sum
  393.  */
  394.  
  395. void db_var_bld_csum(buf)
  396.  BUFFER   buf;
  397. {
  398.     VAR_REC   var;
  399.         int cnt;          
  400.     char *c, *d, csum;
  401.                                 
  402.  
  403.     if (buf->buf_cur_blk == 0) return;
  404.     
  405.     var = (VAR_REC) (buf->buf_data + buf->buf_rec_inx);
  406.     for (cnt=0, csum=0, c = var->var_data; cnt < var->var_dsize; cnt++)
  407.         csum ^= *c++;
  408.  
  409.     *c = csum;
  410.     c  = ((char *)var) + sizeof(struct db_var_rec) + var->var_dsize - 2;
  411.     d  = (char *)&var->var_dsize;
  412.     *c++ = *d++;
  413.     *c   = *d;
  414. }
  415.  
  416. /*
  417.  *      db_var_chk_csum - Check var record check sum
  418.  */
  419.  
  420. void db_var_chk_csum(buf)
  421.  BUFFER   buf;
  422. {
  423.     VAR_REC var;
  424.         short   cnt;          
  425.     char *c, *d, csum;
  426.                                 
  427.     db_error = 0;
  428.  
  429.     if (buf->buf_cur_blk == 0) return;
  430.     
  431.     var = (VAR_REC) (buf->buf_data + buf->buf_rec_inx);
  432.     if (var->var_dsize <= 0 || 
  433.         var->var_dsize > buf->buf_cur_size - sizeof(struct db_var_rec))
  434.     {       db_error = DB_VAR_CSUM_ERROR;
  435.         return;
  436.     }
  437.  
  438.     for (cnt=0, csum=0, c = var->var_data; cnt < var->var_dsize; cnt++)
  439.         csum ^= *c++;
  440.  
  441.     if (*c != csum)
  442.     {       db_error = DB_VAR_CSUM_ERROR;
  443.         return;
  444.     }
  445.  
  446.     c  = ((char *)var) + sizeof(struct db_var_rec) + var->var_dsize - 2;
  447.     d  = (char *)&cnt;
  448.     *d++ = *c++;
  449.     *d   = *c;
  450.  
  451.     if (cnt != var->var_dsize)
  452.     {       db_error = DB_VAR_SIZE_ERROR;
  453.         return;
  454.     }
  455. }
  456.